//
// Created by kaifamiao on 2022/4/4.
//

#ifndef V_TO_ARRAY_PUBLIC_H
#define V_TO_ARRAY_PUBLIC_H

#endif //V_TO_ARRAY_PUBLIC_H
//
// Created by kaifamiao on 2022/3/26.
//

// Created by linrui on 2022/3/23.
//
/* 自定义printf函数的开关 */
#define DEBUG_ENABLE            1

#if DEBUG_ENABLE
//1、获取变量名称
//
//        采用如下宏定义即可，这个宏定义将表达式x直接转换为对应的字符串：
#define varName(x) #x
#define vp(exp) cout<< GREEN<<"变量["<< #exp <<":= "<<(exp)<< "]"<<RESET
#define printExpToString(exp) cout<<(string(#exp)+"为:\t\t")<<(exp).toString()<<endl //注意exp加括号更安全

/* 显示文件名和行数和函数名，后接用户输入的内容 */
#define MY_DEBUG(fmt, args...)   ({printf("%s:%s:line-%d:",__FILE__,__func__,__LINE__);\
                                   printf(fmt"\r\n" ,##args);printf("\n"); })
/* 可以多列举几个自定义print函数，我这就列举一个 */


#else/* 如果没打开开关，MY_DEBUG 就不打印任何东西 */
#define MY_DEBUG(fmt,args...)
#endif

#ifndef FILE_ARRAY_PUBLIC_H
#define FILE_ARRAY_PUBLIC_H

#endif //FILE_ARRAY_PUBLIC_H
//
// Created by linrui on 2022/3/21.
//

#ifndef CPP_READFILE_TOARRAY_PUBLIC_H
#define CPP_READFILE_TOARRAY_PUBLIC_H

#endif //CPP_READFILE_TOARRAY_PUBLIC_H

//
// Created by kaifamiao on 2022/3/19.
//
#define H __LINE__
#define FUNC __func__

#include <cstdio>
#include <iostream>
#include <vector>
#include<io.h>
#include <string.h>
#include<algorithm> //for_each
#include <fstream>

using namespace std;

#include <iomanip>
#include <ctime>

using std::setw;

#ifndef READ_CSV_PUBLIC_H
#define READ_CSV_PUBLIC_H


#endif //READ_CSV_PUBLIC_H
#define FUNC __func__

#define WHITE "\033[0m\033[1;29m"
#define BLACK "\033[0m\033[1;30m"
#define   RED "\033[0m\033[1;31m"
#define GREEN "\033[0m\033[1;32m"
#define YELLOW "\033[0m\033[1;33m"
#define BLUE "\033[0m\033[1;34m"
#define PINK "\033[0m\033[1;35m"
#define CYAN "\033[0m\033[1;36m"
#define GREY "\033[0m\033[1;37m"

#define BBLACK "\033[0m\033[1;40m"
#define   BRED "\033[0m\033[1;41m"
#define BGREEN "\033[0m\033[1;42m"
#define BYELLOW "\033[0m\033[1;43m"
#define BBLUE "\033[0m\033[1;44m"
#define BPINK "\033[0m\033[1;45m"
#define BCYAN "\033[0m\033[1;46m"
#define BGREY "\033[0m\033[1;47m"

#define RESET "\033[0m"

#define ATTEN "\033[0m\033[1;31m"
#define TEST "\033[0m\033[1;33m"
#define INFO "\033[0m\033[1;32m"
#define ERRORS "\033[0m\033[1;41m"
#define WARN "\033[0m\033[1;33m"
#define DEBUG "\033[0m\033[1;34m"
#define SHOW "\033[0m\033[1;36m"
#define GEN "\033[0m\033[1;37m"
#define FATAL "\033[0m\033[1;47m"
int runcount = 1;
namespace str{};
//void print(const char *) {};
//
//template<typename T, typename... Types>
//void print(const T &firstArg, const Types &... args,const char *c="") {
//    cout << firstArg;
//    print(args...);
//}

void p1() {};

template<typename T, typename... Types>
void p1(const T &outstring, const Types &... args) {
    ofstream ouf;
  //  ouf.open("../log.txt",ios::app );
    cout << GREEN << outstring << RESET;
 //   ouf << outstring;
    p1(args...);

   // ouf.close();
}
template<typename T, typename... Types>
void p( const T &message,const Types &... args){
//    ofstream ouf;
//    ouf.open("../log.txt",ios::app );
    cout << "[" << setfill('0') << setw(2) << runcount << "]" << "[" << __TIME__ << "]";
//    ouf << "[" << setfill('0') << setw(2) << runcount << "]" << "[" << __TIME__ << "]";

    p1(message,args...);
//    ouf << "OK";
//    cout <<"\n";
//    ouf <<"\n";
//    ouf.close();
    runcount++;

}


void printl(const char *) {};

template<typename T, typename... Types>
void printl(const char *ch, const T &firstArg, const Types &... args) {
    cout << ch << firstArg << RESET;
    printl(ch, args...);
}

//void vp() {};
//template <typename T, typename... Types>
//void vp(const T& outstring, const Types&... args)
//{
//    printExp(outstring);
//    cout << varName(outstring) <<"="<< outstring;
//    vp(args...);
//}
void logs() {};



template<typename T, typename... Types>
void logs(const T &firstArg, const Types &... args) {
    cout << firstArg;
    logs(args...);
}

void log(string, string) {};

template<typename Ts, typename... Typess>
void log(string name, string info, const Ts &firstArg, const Typess &... args) {
    cout << "[" << setfill('0') << setw(2) << runcount << "]" << "[" << __TIME__ << "]";

    transform(name.begin(), name.end(), name.begin(), ::toupper);

    cout << info << "[" << name << "]" << "\033[0m";
    logs(firstArg, args...);
    cout << "\n";
    runcount++;
}
/*namespace str{
    string touppers(string tostr) {
        transform(tostr.begin(), tostr.end(), tostr.begin(), ::toupper);
        return tostr;
    }

    string tolowers(string tostr) {
        transform(tostr.begin(), tostr.end(), tostr.begin(), ::tolower);
        return tostr;
    }

    string strcolor(string ch, string str) {
        return ch + str + "\033[0m";
    }

}*/

string strcolorA(string ch, string str) {
    transform(str.begin(), str.end(), str.begin(), ::toupper);
    return ch + str + "\033[0m";
}
//string strcolor(char* ch,int str){
//    return ch+ str +"\033[0m";
//}
//}
/*void log(const char *) {};
template <typename TT, typename... Typess>
void log(const TT& firstArg, const Typess&... args)
{
    cout <<firstArg  ;
    log(args...);
}*/
/*void printv(vector<string> v_files){

    for_each(v_files.begin(), v_files.end(), [](string val)->void {  cout << val << endl;});
    printl(YELLOW,"this vector size:",v_files.size(),"\n");

}*/
typedef int FuncType(int, int); //定义了FuncType这种函数数据类型
int exec(FuncType p, int a, int b) {
    log(__func__, ATTEN, "computing running time...");
    time_t begin, end;
    double ret;
    begin = clock();
    int r = p(a, b);
//    cout <<"return p("<<a<<","<<b<<"),result="<<r<<endl;
    end = clock();
    ret = double(end - begin) / CLOCKS_PER_SEC;
    log(FUNC, ATTEN, "runtime:", ret);
    return 0;
}


typedef void FuncTypes(); //定义了FuncType这种函数数据类型
int exec(FuncTypes p) {
    log(__func__, ATTEN, "computing running time...");
    time_t begin, end;
    double ret;
    begin = clock();
    p();
//    cout <<"return p("<<a<<","<<b<<"),result="<<r<<endl;
    end = clock();
    ret = double(end - begin) / CLOCKS_PER_SEC;
    log(FUNC, ATTEN, BRED, "runtime:", ret, RESET);
    return 0;
}
void exec(void (*func)(),int x=0){
    log(__func__, ATTEN, "computing running time...");
    time_t begin, end;
    double ret;
    begin = clock();
    func();
//    printf("\n");
//    cout <<"return p("<<a<<","<<b<<"),result="<<r<<endl;
    end = clock();
    ret = double(end - begin) / CLOCKS_PER_SEC;
    log(FUNC, ATTEN,  "runtime:", BRED,ret, RESET);
}

int sp(string oldstr, string newstr[]) {
    int s = 0;
    for (int i = 0; i < oldstr.length(); i++) { //将字符串分割成字符串数组
        if (oldstr[i] == '\t') {                 //以空格作为分隔符
            s++;
            continue;
        }
        newstr[s] += oldstr[i];                      //将分割好的字符串放到K数组里
    }
    return s;

}
/*template <typename Ts, typename... Typess>
void log(string name,string info,const Ts& firstArg, const Typess&... args){*/
//void info(string);
//void info(string info,const Ts& firstArg, const Typess&... args){
//    logs(firstArg,args);
//}
void gett();

void gettime() {
    time_t rawtime;
    struct tm *ptminfo;
    time(&rawtime);
    ptminfo = localtime(&rawtime);
    printf("current: %02d-%02d-%02d %02d:%02d:%02d\n",
           ptminfo->tm_year + 1900, ptminfo->tm_mon + 1, ptminfo->tm_mday,
           ptminfo->tm_hour, ptminfo->tm_min, ptminfo->tm_sec);

    //gett();
}

//#include <unistd.h>
//#include <sys/time.h>
//#include <windows.h>
//
//void gett(){
//
//    struct timeval time;
//    gettimeofday(&time, NULL);
//    printf("s: %ld, ms: %ld\n", time.tv_sec, (time.tv_sec*1000 + time.tv_usec/1000));
//    printf("获取当前时间 可精确到ms");
//    SYSTEMTIME st = { 0 };
//    GetLocalTime(&st);  //获取当前时间 可精确到ms
//    printf("%d-%02d-%02d %02d:%02d:%02d\n",
//           st.wYear,
//           st.wMonth,
//           st.wDay,
//           st.wHour,
//           st.wMinute,
//           st.wSecond
//
//           );
//
//
//}
class Logger {
public:
    template<typename Ts, typename... Typess>
    static void showinfo(string info, string loginfo, string funcname, const Ts &firstArg, const Typess &... args) {
//        time_t begin,end;
//        gettime();
        time_t now_time;
        now_time = time(NULL);

        cout << "[" << setfill('0') << setw(2) << runcount << "]" << "[" << __TIME__ << "]";
//        cout << "["<< loginfo <<"]";
        transform(funcname.begin(), funcname.end(), funcname.begin(), ::toupper);

        cout << info << "[" << loginfo << "]" << "[" << funcname << "]" << "\033[0m";
        logs(firstArg, args...);
        cout << "\n";

        runcount++;
    }

    template<typename Tsx, typename... Types>
    static void info(string funcname, const Tsx &firstArg, const Types &... args) {
        showinfo(GREEN, "INFO", funcname, firstArg, args...);
    }

    template<typename Tsx, typename... Types>
    static void debug(string funcname, const Tsx &firstArg, const Types &... args) {
        showinfo(BLUE, "DEBUG", funcname, firstArg, args...);
    }

    template<typename Tsx, typename... Types>
    static void trace(string funcname, const Tsx &firstArg, const Types &... args) {
        showinfo(GEN, "TRACE", funcname, firstArg, args...);
    }

    template<typename Tsx, typename... Types>
    static void warn(string funcname, const Tsx &firstArg, const Types &... args) {
        showinfo(ERRORS, "WARN", funcname, firstArg, args...);
    }

    template<typename Tsx, typename... Types>
    static void fatal(string funcname, const Tsx &firstArg, const Types &... args) {
        showinfo(FATAL, "FATAL", funcname, firstArg, args...);
    }

    template<typename Tsx, typename... Types>
    static void error(string funcname, const Tsx &firstArg, const Types &... args) {
        showinfo(PINK, "ERROR", funcname, firstArg, args...);
    }

};
//
//「ALL」: 最低等级的，用于打开所有日志记录。
//
//「TRACE」 : designates finer-grained informational events than the DEBUG.Since:1.2.12，很低的日志级别，一般不会使用。
//
//「DEBUG」:  指出细粒度信息事件对调试应用程序是非常有帮助的，主要用于开发过程中打印一些运行信息。
//
//「INFO」: 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息，这个可以用于生产环境中输出程序运行的一些重要信息，但是不能滥用，避免打印过多的日志。
//
//「WARN」: 表明会出现潜在错误的情形，有些信息不是错误信息，但是也要给程序员的一些提示。
//
//「ERROR」: 指出虽然发生错误事件，但仍然不影响系统的继续运行。打印错误和异常信息，如果不想输出太多的日志，可以使用这个级别。
//
//「FATAL」: 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误，这种级别你可以直接停止程序了。
//
//「OFF」:  最高等级的，用于关闭所有日志记录。
//
//如果将log level设置在某一个级别上，那么比此级别优先级高的log都能打印出来。例如，如果设置优先级为WARN，那么OFF、FATAL、ERROR、WARN4个级别的log能正常输出，而INFO、DEBUG、TRACE、 ALL级别的log则会被忽略。Log4j建议只使用四个级别，优先级从高到低分别是ERROR、WARN、INFO、DEBUG。

class stringbuffer : string {
private:
    string tostr;
    char *tostr_p;

public:
    stringbuffer() {
    }
//    friend ostream & operator<<( ostream & os,const Complex & c);

    //
//    stringbuffer(string tostr){
//        this->tostr = tostr;
//    }
//    CNString::CNString(const char *s) {

    stringbuffer(const char *s) {
        tostr_p = new char[strlen(s) + 1];
        strcpy(tostr_p, s);
    }

    //拷贝构造函数
    stringbuffer(const stringbuffer &c) {
        tostr_p = new char[strlen(c.tostr_p) + 1];
        strcpy(tostr_p, c.tostr_p);
    }

//    CNString& CNString::operator=(const CNString &cn)
    stringbuffer &operator=(const stringbuffer &obj) {
        cout << "operator" << endl;
        this->tostr_p = new char[strlen(obj.tostr_p) + 1];
        strcpy(this->tostr_p, obj.tostr_p);
        return *this;

    };

    stringbuffer operator+(const stringbuffer &A) {
        cout << "operator...+" << endl;
        stringbuffer s;
        s.tostr = this->tostr + A.tostr;
//        cout << s.tostr <<endl;
        return s;
    };

    friend ostream &operator<<(ostream &os, const stringbuffer &a) {
        os << a.tostr_p;
        return os;
    }

    string toupper(string tostr) {
        transform(tostr.begin(), tostr.end(), tostr.begin(), ::toupper);
        return tostr;
    }

    string toupper() {
        string tostr = this->tostr;
        transform(tostr.begin(), tostr.end(), tostr.begin(), ::toupper);
        return tostr;
    }

    string tolower(string tostr) {
        transform(tostr.begin(), tostr.end(), tostr.begin(), ::tolower);
        return tostr;
    }

    int length(string tostr) {
        return tostr.size();
    }

    int length() {
        return this->tostr.size();
    }

    void print() {
        cout << "tostr_p = " << tostr_p << endl;
    }
};


class Test : string {
    string *m_pointer;
    char *m_s;
public:
    Test() {

    }

    ///构造函数
    Test(const char *s) {
        m_s = new char[strlen(s) + 1];
        strcpy(m_s, s);
    }

    Test(const Test &c) {
        m_s = new char[strlen(c.m_s) + 1];
        strcpy(m_s, c.m_s);
    }

    Test &operator=(const Test &cn) {
        this->m_s = new char[strlen(cn.m_s) + 1];
        strcpy(this->m_s, cn.m_s);
        return *this;
    }

    void print() {
        cout << "m_pointer = " << m_s << endl;
    }

    ~Test() {
        delete m_s;
        m_s = nullptr;
    }
};

#ifndef CNSTRING_H
#define CNSTRING_H

class CString {
public:
    CString &operator=(const CString &cn);//重构=
    CString operator+(const CString &cn);//重构+
    char operator[](int index);//重构[]
    bool operator<(const CString &cn);//重构<
    bool operator>(const CString &cn);//重构>
    bool operator==(const CString &cn);//重构==
    CString();//默认构造函数
    CString(const char *s);//构造函数
    CString(const CString &c);//拷贝构造函数
    ~CString();//析构函数
    friend ostream &operator<<(ostream &os, const CString &obj) {
        os << obj.m_s;
        return os;
    }

    void display();//输出数据
public:
    char *m_s;
};

#endif //TEST1_CNSTRING_H

//重载运算符：=
CString &CString::operator=(const CString &cn) {
    this->m_s = new char[strlen(cn.m_s) + 1];
    strcpy(this->m_s, cn.m_s);
    return *this;
}

//重载运算符：+
CString CString::operator+(const CString &cn) {
    CString temp;
    temp.m_s = new char[strlen(this->m_s) + strlen(cn.m_s) + 1];
    strcpy(temp.m_s, this->m_s);
    strcat(temp.m_s, cn.m_s);
    return temp;
}

//重载运算符：[]
char CString::operator[](int index) {
    if (index >= strlen(this->m_s)) {
        return '\0';
    }
    return this->m_s[index];
}

//重载运算符：<
bool CString::operator<(const CString &cn) {
    if (strcmp(this->m_s, cn.m_s) < 0) {
        return true;
    }
    return false;
}

//重载运算符：>
bool CString::operator>(const CString &cn) {
    if (strcmp(this->m_s, cn.m_s) > 0) {
        return true;
    }
    return false;
}

//重载运算符：==
bool CString::operator==(const CString &cn) {
    if (strcmp(this->m_s, cn.m_s) == 0) {
        return true;
    }
    return false;
}

//默认构造函数
CString::CString() {
    this->m_s = new char('\0');
}

//构造函数
CString::CString(const char *s) {
    m_s = new char[strlen(s) + 1];
    strcpy(m_s, s);
}

//拷贝构造函数
CString::CString(const CString &c) {
    m_s = new char[strlen(c.m_s) + 1];
    strcpy(m_s, c.m_s);
}

//析构函数
CString::~CString() {
    delete m_s;
    m_s = nullptr;
}

//输出数据
void CString::display() {
    std::cout << m_s << std::endl;
}
//int main()
//{
//    Test t1 = 1;
//    Test t2;
//
//    t2 = t1;  // 默认赋值操作符的浅拷贝使得两个对象内部指针指向同一片空间；
//
//    int i = 0;  // C 语言中允许这样，所以 C++ 中也必须允许；
//    i = i;
//
//    t2 = t2;  // C++  中也要允许自赋值，但是没有意义；
//
//    t1.print();
//    t2.print();
//
//    return 0;
//}
/*


class Test
{
    int* m_pointer;
public:
    Test()
    {
        m_pointer = NULL;
    }
    Test(int i)
    {
        m_pointer = new int(i);
    }
    Test(const Test& obj)
    {
        m_pointer = new int(*obj.m_pointer);
    }
    Test& operator = (const Test& obj)
    {
        if( this != &obj )  // 避免自赋值；
        {
            delete m_pointer;
            m_pointer = new int(*obj.m_pointer);
        }

        return *this;
    }
    void print()
    {
        cout << "m_pointer = " << hex << m_pointer << endl;
    }
    ~Test()
    {
        delete m_pointer;
    }
};*/


class CAnyType //: public CObject
{
public:
    CAnyType() {};

    //DECLARE_SERIAL(CAnyType)
    ~CAnyType() {};

protected:

    string DataType;
    // union还可以用来判断大端还是小端
    union {
        int myint;
        double mydouble;
        float myfloat;
        wchar_t mychar;
    } value;

public:
    CAnyType operator=(const int &in) {
        value.myint = in;
        DataType = "int";
        return *this;
    }

    CAnyType operator=(const wchar_t &in) {
        value.mychar = in;
        DataType = "char";
        return *this;
    }

    CAnyType operator=(const float &in) {
        value.myfloat = in, DataType = "float";
        return *this;
    }

    CAnyType operator=(const double &in) {
        value.mydouble = in;
        DataType = "double";
        return *this;
    }

    friend std::ostream &operator<<(std::ostream &os, const CAnyType &ca) {
        os << ca.value.mydouble << std::endl;
        return os;
    };
};
//C++ 获取文件夹下的所有文件名
/*
vector<string>  getFiles( const string& path) {
    //文件句柄
    long hFile;
    //文件信息
    struct _finddata_t fileinfo{};
    vector<string> files;
    string p;
    if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1) {
        do {
            //如果是目录,迭代之
            //如果不是,加入列表
            if ((fileinfo.attrib & _A_SUBDIR)) {
                if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
                    getFiles(p.assign(path).append("\\").append(fileinfo.name));
            } else {
                files.push_back(p.assign(path).append("\\").append(fileinfo.name));
            }
        } while (_findnext(hFile, &fileinfo) == 0);
        _findclose(hFile);
    }
    return files;
}

vector<string> getFiles(string path,string exteName)
{

    vector<string> files;
    char *to_search;        //欲查找的文件，支持通配符
    path=path+exteName;
    strcpy(to_search,path.c_str());//用到 c_str()函数
    long handle;                                                //用于查找的句柄
    struct _finddata_t fileinfo;                          //文件信息的结构体
    handle=_findfirst(to_search,&fileinfo);         //第一次查找
    if(-1==handle)
        files.push_back("NODATA");;
    ///printf("%s\n",fileinfo.name);                         //打印出找到的文件的文件名
    files.push_back(fileinfo.name);
    while(!_findnext(handle,&fileinfo))               //循环查找其他符合的文件，知道找不到其他的为止
    {
        files.push_back(fileinfo.name);
        //printf("%s\n",fileinfo.name);
    }
    _findclose(handle);                                      //别忘了关闭句柄
    return files;
}
vector<string> getAllFiles( string path)
{
    //文件句柄
    vector<string> files;
    long  hFile  =  0;
    //文件信息
    struct _finddata_t fileinfo;
    string p;
    if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo)) != -1)
    {
        do
        {
            if((fileinfo.attrib & _A_SUBDIR))
            {
                if(strcmp(fileinfo.name,".") != 0 && strcmp(fileinfo.name,"..") != 0)
                {
                    files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
                    getAllFiles( p.assign(path).append("\\").append(fileinfo.name) );
                }
            }
            else
            {
                files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
            }
        }while(_findnext(hFile, &fileinfo) == 0);
        _findclose(hFile);
        return files;
    }
}*/
void printf_red(const char *s) {
    printf("\033[0m\033[1;31m%s\033[0m", s);
}

void printf_green(const char *s) {
    printf("\033[0m\033[1;32m%s\033[0m", s);
}

void printf_yellow(const char *s) {
    printf("\033[0m\033[1;33m%s\033[0m", s);
}

void printf_blue(const char *s) {
    printf("\033[0m\033[1;34m%s\033[0m", s);
}

void printf_pink(const char *s) {
    printf("\033[0m\033[1;35m%s\033[0m", s);
}

void printf_cyan(const char *s) {
    printf("\033[0m\033[1;36m%s\033[0m", s);
}
//#include <string_view>
//#include <source_location>
//template <typename T>
//void logsss(const T message,
//         const std::source_location location =
//         std::source_location::current())
//{
//    std::cout << "file: "
//              << location.file_name() << "("
//              << location.line() << ":"
//              << location.column() << ") `"
//              << location.function_name() << "`: "
//              << message << '\n';
//}
//
//template <typename T> void fun(T x)
//{
//    logsss(123);
//}

template<typename ... Types>
void print4(const Types &... args) {

    cout << "[" << __TIME__ << "]";

    initializer_list<int>{([&args] {
        log(args);
        cout << args;
    }(), 0)...};

    cout << "[end]";

}
template<typename T>
void print_vecter(vector<T> vec){
    p("this vecor size =",vec.size());
    for (auto v_str: vec) {
        cout <<"\t"<<GREEN << v_str << "\t[" << v_str.length() << "]" << RESET<<endl;
    }
}

namespace str {
    string buwei(string s){
        if(s.length()<2)
            return "0"+s;
        else
            return s;
    }
    string getdate() {
        time_t rawtime;
        struct tm *ptminfo;
        time(&rawtime);
        ptminfo = localtime(&rawtime);
        return to_string(ptminfo->tm_year + 1900) +"-"+ buwei(to_string(ptminfo->tm_mon + 1)) +"-"+ buwei(to_string(ptminfo->tm_mday));
        //, , ptminfo->tm_hour, ptminfo->tm_min, ptminfo->tm_sec);
        //gett();
    }
    string gettime() {
        time_t rawtime;
        struct tm *ptminfo;
        time(&rawtime);
        ptminfo = localtime(&rawtime);

        return to_string(ptminfo->tm_hour ) +":"+ to_string(ptminfo->tm_min) +":"+ to_string(ptminfo->tm_sec);
        //, , ptminfo->tm_hour, ptminfo->tm_min, ptminfo->tm_sec);
        //gett();
    }
    string getweek() {
        time_t rawtime;
        struct tm *ptminfo;
        time(&rawtime);
        ptminfo = localtime(&rawtime);

        return to_string(ptminfo->tm_wday);
        //, , ptminfo->tm_hour, ptminfo->tm_min, ptminfo->tm_sec);
        //gett();
    }
    string now(){
        return getdate()+" "+ gettime();
    }

    void str_to_array(const string &old_str, char flag ,string new_str[]) {
        int s = 0;
        for (char i: old_str) {
            if (i == flag) {
                s++;
                continue;
            }
            new_str[s] += i;
        }
    }

    template <typename T>
    string to_str(T str){
        return to_string(str);
    }

    string toupper(string tostr) {
        transform(tostr.begin(), tostr.end(), tostr.begin(), ::toupper);
        return tostr;
    }

    string tolower(string tostr) {
        transform(tostr.begin(), tostr.end(), tostr.begin(), ::tolower);
        return tostr;
    }

    //取得字符串长度,用strlen也可以代替
    int len(const string &cstr) {
        return cstr.length();
    }

    string strcolor(string ch, string str) {
        return ch + str + "\033[0m";
    }

    //从右边取自定义个数字符格式(目标，源，数量)
    string right(string fromstr, int start = 0, int num = 1) {
        int i;
        string to_str, to_tmp;
        int StatrNum = fromstr.length() - num - (start);
        if (num > fromstr.length()) {
            return "function rigth string " + fromstr + ",length error!";
        }
        for (i = 0; i < num; i++) {
            to_str[i] = fromstr[i + StatrNum];
            to_tmp += to_str[i];
        }
        return to_tmp;
    }

    //从左边取自定义个数字符格式(目标，源，数量)
    string left(string fromstr, int start = 0, int num = 1) {
        string to;
        string tmp_str;
        int i;
        if (num > fromstr.length()) {
            return "function rigth string " + fromstr + ",length error!";
        }
        if(start >num){
            num =start+num;
        }
        for (i = start; i < num; i++) {
            to[i] = fromstr[i];
            tmp_str += to[i];
        }
        return tmp_str;
    }
    string reverse(string strs){
        reverse(strs.begin(),strs.end());
        return strs;
    }
    string replace(const string &oldstr, const char flag, const string repstr) {
        int s = 0;
        string newstr;
        for (char i: oldstr) {
            if (i == flag) {
                s++;
                newstr += repstr;
                continue;
            }
            newstr += i;
        }
        return newstr;
    }


    string replace( string &str, const string flag, const string repstr) {
        int pos;
        pos = str.find(flag);
        while(pos != -1){
            // str.length()求字符的长度，注意str必须是string类型
            str.replace(pos,string(flag).length(),repstr);
            pos = str.find(flag);
        }
        return str;
    }
    /* 字符串截取 */
    string getSubString(string s,int pos,int n){
        // substr(pos)函数的使用，返回从pos开始(包含pos位置的字符)所有的字符
//    cout << str.substr(2) << endl;
//    // substr(pos,n)，返回从pos开始(包含pos位置的字符)n个字符
//    cout << str.substr(pos, n) << endl;
        return s.substr(pos,n);
    }
    //从左边查找有无匹配字符串
    int Instr(string Txt, const string Word) {
        int i, s;
        int WordNum = Word.length();
        int TxtNum = Txt.length();
        int InstrNum = 0;
        if (TxtNum > WordNum) {
            for (i = 0; i < TxtNum; i++) {
                if (s = WordNum) {
                    InstrNum = i;
                    break;
                }
                for (s = 0; s < WordNum; s++, i++) {

                    if (Word[s] == Txt[i]) {
                        continue;
                    } else {
                        if (InstrNum == 0)
                            InstrNum = 0;
                        cout <<s <<endl;
                        break;
                    }

                }
            }
//if(InstrNum!=0)
//InstrNum=InstrNum-WordNum;
        }
        return InstrNum;
    }

//从右边查找有无匹配字符串
    int InstrRev(string Txt, string Word) {
        int i, s;
        int WordNum = Word.length();
        int TxtNum = Txt.length();
        int InstrRevNum = 0;
        if (TxtNum > WordNum) {
            for (i = TxtNum; i > 0; i--) {
                InstrRevNum = i;
                for (s = WordNum; s > 0; s--, i--) {
                    if (Word[s] == Txt[i]) {
                        continue;
                    } else
                        break;
                }
            }
//InstrNum=TxtNum-(InstrNum+WordNum)+1;
        }
        return InstrRevNum;
    }

}